package com.arvin.faceDetect.ui.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Matrix
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.view.View
import com.google.mlkit.vision.face.Face
import com.google.mlkit.vision.face.FaceLandmark

class FaceOverlayView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    private val facePaint = Paint().apply {
        color = Color.GREEN
        style = Paint.Style.STROKE
        strokeWidth = 5f
        isAntiAlias = true
    }

    private val eyePaint = Paint().apply {
        color = Color.GREEN
        style = Paint.Style.STROKE
        strokeWidth = 3f
        isAntiAlias = true
    }

    private var faces: List<Face> = emptyList()
    private var showFaceRect = true
    private var showEyeRect = true
    private var previewWidth = 0
    private var previewHeight = 0
    private var imageWidth = 0
    private var imageHeight = 0
    private var rotation = 0
    private var isFrontCamera = true
    private var transformationMatrix = Matrix()
    private var needUpdateTransformation = true

    fun updateFaces(
        faces: List<Face>,
        showFaceRect: Boolean,
        imageWidth: Int,
        imageHeight: Int,
        rotation: Int,
        isFrontCamera: Boolean = true,
        showEyeRect: Boolean = true
    ) {
        this.faces = faces
        this.showFaceRect = showFaceRect
        this.imageWidth = imageWidth
        this.imageHeight = imageHeight
        this.rotation = rotation
        this.isFrontCamera = isFrontCamera
        this.showEyeRect = showEyeRect
        needUpdateTransformation = true
        invalidate()
    }

    private fun updateTransformationIfNeeded() {
        if (!needUpdateTransformation) return

        transformationMatrix.reset()
        
        // 计算缩放比例
        val scaleX = previewWidth.toFloat() / imageWidth.toFloat()
        val scaleY = previewHeight.toFloat() / imageHeight.toFloat()
        val scale = minOf(scaleX, scaleY)
        
        // 计算居中偏移量
        val dx = (previewWidth - imageWidth * scale) / 2f
        val dy = (previewHeight - imageHeight * scale) / 2f

        // 1. 缩放
        transformationMatrix.postScale(scale, scale)

        // 2. 平移
        transformationMatrix.postTranslate(dx, dy)

        // 3. 前置相机需要水平镜像
        if (isFrontCamera) {
            transformationMatrix.postScale(-1f, 1f, previewWidth / 2f, previewHeight / 2f)
        }

        needUpdateTransformation = false
    }

    override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
        super.onLayout(changed, left, top, right, bottom)
        if (changed) {
            needUpdateTransformation = true
        }
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        if (faces.isEmpty() || previewWidth == 0 || previewHeight == 0) return

        updateTransformationIfNeeded()

        for (face in faces) {
            if (showFaceRect) {
                // 计算人脸中心点
                val box = face.boundingBox
                val centerX = (box.left + box.right) / 2f
                val centerY = (box.top + box.bottom) / 2f
                
                // 缩小人脸框，保持中心点不变
                val faceWidth = box.width() * 0.85f
                val faceHeight = box.height() * 0.85f
                
                val rect = RectF(
                    centerX - faceWidth / 2,
                    centerY - faceHeight / 2,
                    centerX + faceWidth / 2,
                    centerY + faceHeight / 2
                )
                
                transformationMatrix.mapRect(rect)
                canvas.drawRect(rect, facePaint)
            }

            if (showEyeRect) {
                drawEyeRect(canvas, face)
            }
        }
    }

    private fun drawEyeRect(canvas: Canvas, face: Face) {
        val leftEye = face.getLandmark(FaceLandmark.LEFT_EYE)
        val rightEye = face.getLandmark(FaceLandmark.RIGHT_EYE)

        if (leftEye != null && rightEye != null) {
            // 计算两眼之间的距离
            val eyeDistance = Math.hypot(
                (rightEye.position.x - leftEye.position.x).toDouble(),
                (rightEye.position.y - leftEye.position.y).toDouble()
            ).toFloat()

            // 计算两眼的中心点
            val eyesCenterX = (leftEye.position.x + rightEye.position.x) / 2f
            val eyesCenterY = (leftEye.position.y + rightEye.position.y) / 2f

            // 根据人脸旋转角度调整眼睛区域大小
            val rotationY = Math.abs(face.headEulerAngleY)
            // 增加基础比例，使眼睛框更宽
            val eyeScale = if (rotationY > 30) 0.6f else if (rotationY > 15) 0.5f else 0.4f

            // 创建包含两只眼睛的矩形区域
            val eyeRegion = if (!isFrontCamera && (rotation == 90 || rotation == 270)) {
                // 后置摄像头且旋转90度或270度时
                // 增加宽度系数，使眼睛框更宽
                val width = eyeDistance * 1.4f  // 增加到2.0倍眼距
                val height = eyeDistance * 0.4f // 增加到0.6倍眼距

                RectF(
                    eyesCenterX - width / 2,  // 确保以两眼中心点为中心
                    eyesCenterY - height / 2,
                    eyesCenterX + width / 2,
                    eyesCenterY + height / 2
                )
            } else {
                // 前置相机或不需要旋转时
                // 使用眼睛中心点来确定矩形位置
                val width = eyeDistance * (1 + eyeScale * 2)  // 增加宽度
                val height = eyeDistance * eyeScale

                RectF(
                    eyesCenterX - width / 2,  // 以两眼中心点为中心
                    Math.min(leftEye.position.y, rightEye.position.y) - height,
                    eyesCenterX + width / 2,
                    Math.max(leftEye.position.y, rightEye.position.y) + height
                )
            }

            // 确保眼睛区域在图像范围内
            eyeRegion.apply {
                left = left.coerceIn(0f, imageWidth.toFloat())
                top = top.coerceIn(0f, imageHeight.toFloat())
                right = right.coerceIn(0f, imageWidth.toFloat())
                bottom = bottom.coerceIn(0f, imageHeight.toFloat())
            }

            // 转换并绘制眼睛区域
            val transformedEyeRegion = RectF(eyeRegion)
            transformationMatrix.mapRect(transformedEyeRegion)
            canvas.drawRect(transformedEyeRegion, eyePaint)
        }
    }

    fun setPreviewSize(width: Int, height: Int) {
        previewWidth = width
        previewHeight = height
        needUpdateTransformation = true
        invalidate()
    }

    fun setShowFaceRect(show: Boolean) {
        showFaceRect = show
        invalidate()
    }

    fun setShowEyeRect(show: Boolean) {
        showEyeRect = show
        invalidate()
    }
} 